#pragma once
#include "mysql_ptime_traits.hpp"
#include "mysql.hpp"
#include "message.hxx"
#include "message-odb.hxx"

namespace suye
{
class MessageTable {
public:
    using ptr = std::shared_ptr<MessageTable>;
    MessageTable(const std::shared_ptr<odb::core::database> db): _db(db) {}
    ~MessageTable() {}

    bool insert(Message& msg) 
    {
        try {
            //获取事务对象开启事务
            odb::transaction trans(_db->begin());
            _db->persist(msg);
            // 提交事务
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("新增消息失败：{}-{}！", msg.message_id(), e.what());
            return false;
        }
        return true;
    }

    bool remove(const std::string& ssid) 
    {   
        try {
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            _db->erase_query<Message>(query::session_id == ssid);
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("删除指定会话中的所有消息失败：{}:{}！", ssid, e.what());
            return false;
        }
        return true;
    }

    // 本次查询是以ssid作为过滤条件，然后进行以时间字段进行逆序，再通过limit查询
    std::vector<Message> recent(const std::string& ssid, int count)
    {
        std::vector<Message> res;
        try {
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;
            std::stringstream cond;
            cond << "session_id='" << ssid << "' "; 
            cond << "order by create_time desc limit " << count;   
            result r(_db->query<Message>(cond.str()));
            for (auto it = r.begin(); it != r.end(); ++it) {
                res.push_back(*it);
            }
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("获取最近消息失败：{}-{}-{}！", ssid, count, e.what());
        }
        return res;
    }

    // 获取指定会话指定时间段的消息
    std::vector<Message> range(const std::string& ssid, 
        boost::posix_time::ptime& stime, 
        boost::posix_time::ptime& etime)
    {
        std::string stime_str = boost::posix_time::to_simple_string(stime);
        std::string etime_str = boost::posix_time::to_simple_string(etime);
        std::vector<Message> res;
        try {
            odb::transaction trans(_db->begin());
            typedef odb::query<Message> query;
            typedef odb::result<Message> result;
            result r(_db->query<Message>(query::session_id == ssid && 
                                        query::create_time >= stime &&
                                        query::create_time <= etime));
            for (auto it = r.begin(); it != r.end(); ++it) {
                res.push_back(*it);
            }
            trans.commit();
        } catch(std::exception& e) {
            LOG_ERROR("获取区间消息失败：{}-{}:{}-{}！", ssid, stime_str, etime_str, e.what());
        }
        return res;
    }

private:
    std::shared_ptr<odb::core::database> _db;
};
}